﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditorInternal;

namespace UIFramework.Editor
{
    public class UIFrameworkSetup
    {
        static string[] _sortingLayers = new string[] { UISortLayer.UI_Bottom, UISortLayer.UI_Middle, UISortLayer.UI_Top };

        [MenuItem("UITools/Setup UI Framework")]
        static void SetupTags()
        {
            Debug.Log("检查 UI Tag");
            string[] str = InternalEditorUtility.tags;
            HashSet<string> tags = new HashSet<string>();
            for (int i = 0; i < str.Length; i++)
            {
                tags.Add(str[i]);
            }
            CheckTag(UITag.All, tags);
            CheckTag(UITag.ExceptGobj, tags);
            CheckTag(UITag.Gobj, tags);
            CheckTag(UITag.Nuclear, tags);
            Debug.Log("检查完成");

            Debug.Log("检查 Sorting Layer");
            CheckSortLayers();
            Debug.Log("检查完成");

        }

        static void CheckTag(string tag, HashSet<string> tagSet)
        {
            if (!tagSet.Contains(tag))
            {
                Debug.Log("添加 UI Tag：" + tag);
                InternalEditorUtility.AddTag(tag);
            }
        }

        static void CheckSortLayers()
        {
            if (!TryGetSortingLayerConfig(out var tagManager, out var sortlayerProperty))
            {
                Debug.LogError("Sort Layer 设置失败");
                return;
            }
            
            int sortLayerCount = sortlayerProperty.arraySize;
            HashSet<string> tmpSet = new HashSet<string>();
            for (int i = 0; i < sortLayerCount; i++)
            {
                SerializedProperty dataPoint = sortlayerProperty.GetArrayElementAtIndex(i);
                string name = dataPoint.FindPropertyRelative("name").stringValue;
                if (!tmpSet.Add(name))
                {
                    Debug.LogError($"当前Sort Layer 配置中有命名重复：{name}");
                }
            }
            if (tmpSet.IsSupersetOf(_sortingLayers))
            {
                return;
            }
            tmpSet.Clear();
            for (int i = 0; i < _sortingLayers.Length; i++)
            {
                tmpSet.Add(_sortingLayers[i]);
            }
            //清除可能存在的个别layer的情况
            for (int i = sortLayerCount -1; i >= 0; i--)
            {
                SerializedProperty dataPoint = sortlayerProperty.GetArrayElementAtIndex(i);
                string name = dataPoint.FindPropertyRelative("name").stringValue;
                if (tmpSet.Contains(name))
                {
                    sortlayerProperty.DeleteArrayElementAtIndex(i);
                    tagManager.ApplyModifiedProperties();
                }
            }
            

            //添加layer
            for (int i = 0; i < _sortingLayers.Length; i++)
            {
                sortlayerProperty.InsertArrayElementAtIndex(sortlayerProperty.arraySize);
                var tmpPro = sortlayerProperty.GetArrayElementAtIndex(sortlayerProperty.arraySize - 1);
                tmpPro.FindPropertyRelative("name").stringValue = _sortingLayers[i];
                tmpPro.FindPropertyRelative("uniqueID").intValue = (int)((System.DateTime.Now.Ticks + i * 100) % int.MaxValue);//用于保证唯一性的ID
            }
            tagManager.ApplyModifiedProperties();
            EditorUtility.SetDirty(tagManager.targetObject);
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();

            ApplySortLayerToUIRootPrefab();

        }

        static bool TryGetSortingLayerConfig(out SerializedObject tagManager, out SerializedProperty sortlayerProperty)
        {
            tagManager = new SerializedObject(AssetDatabase.LoadAssetAtPath<UnityEngine.Object>("ProjectSettings/TagManager.asset"));
            sortlayerProperty = tagManager.GetIterator();
            while (sortlayerProperty.NextVisible(true))
            {
                if (sortlayerProperty.name == "m_SortingLayers")
                {
                    return true;
                }
            }
            return false;
        }

        static void ApplySortLayerToUIRootPrefab()
        {
            GameObject uiroot = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/UIFramework/Prefab/UIRoot.prefab");
            Canvas[] canvasArr = new Canvas[] {
                uiroot.transform.Find("BottomCanvas").GetComponent<Canvas>(),
                uiroot.transform.Find("MiddleCanvas").GetComponent<Canvas>(),
                uiroot.transform.Find("TopCanvas").GetComponent<Canvas>(),
            };
            for (int i = 0; i < _sortingLayers.Length; i++)
            {
                canvasArr[i].sortingLayerName = _sortingLayers[i];
            }
            PrefabUtility.SavePrefabAsset(uiroot);
            AssetDatabase.Refresh();
        }
    }

}
